"""
通过字符串调用对象方法

问题：
    你有一个字符串形式的方法名称，想通过它调用某个对象的对应方法。
解决方案：
    最简单的情况，可以使用 getattr()。
    另外一种方法是使用 operator.methodcaller()。
"""

import math
import operator


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return "Point({!r:}, {!r:})".format(self.x, self.y)

    def distance(self, x, y):
        return math.hypot(self.x - x, self.y - y)


def use_getattr():
    p = Point(1, 2)
    d = getattr(p, "distance")(0, 0)
    print(d)
    # 输出结果：
    """
    2.23606797749979
    """


def use_operator():
    p = Point(1, 2)
    print(operator.methodcaller("distance", 0, 0)(p))
    # 输出结果：
    """
    2.23606797749979
    """

    points = [
        Point(1, 2),
        Point(3, 0),
        Point(0, 1),
    ]

    points.sort(key=operator.methodcaller("distance", 0, 0))
    print(points)
    # 输出结果：
    """
    [Point(0, 1), Point(1, 2), Point(3, 0)]
    """


if __name__ == '__main__':
    use_getattr()
    use_operator()
